/**
 * Copyright (c) 2021-2028, iron.guo 郭成杰 (jiedreams@sina.com).
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.beluga.core.service.impl;

import com.beluga.core.model.wechat.*;
import com.beluga.core.notify.WxPayRefundNotifyResult;
import com.beluga.core.pay.BPayModel;
import com.beluga.core.pay.SignType;
import com.beluga.core.pay.TradeType;
import com.beluga.core.props.WxPayProperties;
import com.beluga.core.service.WxPayService;
import com.beluga.core.util.WxPayTools;
import com.beluga.core.wechat.WechatPayApi;
import com.beluga.core.xml.XmlConfig;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

/**
 * @Author iron.guo
 * @Date 2022/5/3
 * @Description
 */
@Service
@Slf4j
@AllArgsConstructor
public class IWxPayService implements WxPayService {

    private WxPayProperties wxPayProperties;

    /**
     * 获取微信支付令牌
     * @param unifiedOrder
     * @return
     */
    @Override
    public WxPayResult.JsapiResult payToken(WxBPayUnifiedOrder unifiedOrder) {
        unifiedOrder.checkAndSign(wxPayProperties.getMchKey());
        String result = WechatPayApi.pushOrder(false, unifiedOrder);
        WxBPayUnifiedResult wxBPayUnifiedResult = BaseWxPayResult.fromXML(result, WxBPayUnifiedResult.class);
        WxPayResult.JsapiResult payinfo=BPayModel.getWxPayInfo(TradeType.JSAPI,wxBPayUnifiedResult.getPrepayId(),SignType.HMACSHA256,wxPayProperties);
        return payinfo;
    }

    /**
     * 查询微信订单
     * @param transactionId
     * @param outTradeNo
     * @return
     */
    @Override
    public WxBPayOrderQuery queryWxOrder(String transactionId, String outTradeNo) {
        WxBPayOrderRequest request=new WxBPayOrderRequest();
        request.setOutTradeNo(StringUtils.trimToNull(outTradeNo));
        request.setTransactionId(StringUtils.trimToNull(transactionId));
        request.setNonceStr(WxPayTools.generateStr());
        request.setSignType(SignType.MD5.getType());
        request.checkAndSign(wxPayProperties);
        String order = WechatPayApi.queryOrder(request);
        WxBPayOrderQuery orderQuery = WxBPayOrderQuery.fromXML(order, WxBPayOrderQuery.class);
        return orderQuery;
    }

    /**
     * 关闭微信订单
     * @param outTradeNo
     * @return
     */
    @SneakyThrows
    @Override
    public WxBPayOrderCloseResult closeWxOrder(String outTradeNo) {
        if (StringUtils.isBlank(outTradeNo)) {
            throw new Exception("out_trade_no不能为空");
        }
        WxBPayOrderCloseRequest request = new WxBPayOrderCloseRequest();
        request.setNonceStr(WxPayTools.generateStr());
        request.setOutTradeNo(StringUtils.trimToNull(outTradeNo));
        request.checkAndSign(wxPayProperties);
        String xmlData = WechatPayApi.closeOrder(request);
        WxBPayOrderCloseResult result = BaseWxPayResult.fromXML(xmlData, WxBPayOrderCloseResult.class);
        return result;
    }

    /**
     * 微信退款
     * @param request
     * @return
     */
    @Override
    public WxBPayRefundResult wxRefund(WxBPayRefundRequest request) {
        request.setNonceStr(WxPayTools.generateStr());
        request.setOutRefundNo(WxPayTools.generateStr());
        request.checkAndSign(wxPayProperties);
        String xmlData = WechatPayApi.orderRefund(false,request,wxPayProperties.getKeyPath(),wxPayProperties.getMchId());
        WxBPayRefundResult result = BaseWxPayResult.fromXML(xmlData, WxBPayRefundResult.class);
        return result;
    }

    @Override
    public WxPayRefundNotifyResult parseWxRefundNotifyResult(String xmlData) {
        log.debug("微信支付退款异步通知参数：{}", xmlData);
        WxPayRefundNotifyResult result;
        if (XmlConfig.fastMode) {
            result = BaseWxPayResult.fromXML(xmlData, WxPayRefundNotifyResult.class);
            result.decryptReqInfo(wxPayProperties.getMchKey());
        } else {
            result = WxPayRefundNotifyResult.fromXML(xmlData,wxPayProperties.getMchKey());
        }
        log.debug("微信支付退款异步通知解析后的对象：{}", result);
        return result;
    }

    @Override
    public WxBPayRefundQueryResult refundQuery(WxBPayRefundQueryRequest request) {
        request.setNonceStr(WxPayTools.generateStr());
        request.checkAndSign(wxPayProperties);
        String xmlData = WechatPayApi.queryRefund(request);
        WxBPayRefundQueryResult result = WxBPayRefundQueryResult.fromXML(xmlData, WxBPayRefundQueryResult.class);
        return result;
    }


    public static void main(String[] args) {
        //查询订单
        WxBPayOrderRequest request=new WxBPayOrderRequest();
        request.setMchId("1616239829");
        request.setAppid("wx767db2bfa6f5bbcd");
        request.setOutTradeNo("X-394998686591881216");
        request.setTransactionId("4200001417202205046611934154");
        request.setNonceStr(WxPayTools.generateStr());
        request.setSignType(SignType.MD5.getType());
        request.checkAndSign("xindongli88888888888888888888888");
        System.out.println(request.toXML());
        String order = WechatPayApi.queryOrder(request);
        System.out.println(order);
        WxBPayOrderQuery orderQuery = WxBPayOrderQuery.fromXML(order, WxBPayOrderQuery.class);
        System.out.println(orderQuery);
    }
}
